package com.fau.fm.aop;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.fau.fm.dao.IBaseDao;
import com.fau.fm.entity.MedicalAdmin;
import com.fau.fm.entity.MedicalFinancialClaim;
import com.fau.fm.entity.MedicalFinancialOrders;
import com.fau.fm.entity.MedicalOrderReconClaim;
import com.fau.fm.entity.MedicalOrderReconciliation;
import com.fau.fm.entity.MedicalOrdersLog;
import com.fau.fm.entity.MedicalOrdersStorage;
import com.fau.fm.util.SystemConfig;

/**
 * @desc 产品销售量统计  订单状态：对账、回款
 * @author dangjh
 * @datetime 2014年12月12日 下午5:23:36
 */
@Aspect
@Component
public class ProductSalesStaAop {

	@Resource
	private IBaseDao iBaseDao;
	
	/**
	 * @desc 待对账列表-对账切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:22:04
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.updateWaitClaim(..))")
	private void updateWaitClaim() {}
	
	/**
	 * @desc 待对账列表——已对账
	 * @author dangjh
	 * @datetime 2014年12月11日 下午4:47:20
	 */
	@AfterReturning("updateWaitClaim()")
	public void updateWaitClaim(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		MedicalFinancialClaim order = (MedicalFinancialClaim) obj[0];
		String[] ids = order.getOrderId().split(",");
		for(String id : ids) {
			// 订单操作日志记录
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("待对账操作   订单对账");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.HAS_RECONCILED, id);
		}
	}
	
	/**
	 * @desc 我的待对账列表-对账切点
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:34:49
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.update(..))")
	private void update() {}
	
	/**
	 * @desc 我的待对账列表——已对账
	 * @author dangjh
	 * @datetime 2014年12月11日 下午4:47:20
	 */
	@AfterReturning("update()")
	public void update(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		MedicalFinancialClaim order = (MedicalFinancialClaim) obj[0];
		String[] ids = order.getOrderId().split(",");
		for(String id : ids) {
			// 订单操作日志记录
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("我的待对账操作   订单对账");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.HAS_RECONCILED, id);
		}
	}
	
	/**
	 * @desc 待回款列表-回款切点
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:34:49
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.saveWaitRecon(..))")
	private void saveWaitRecon() {}
	
	/**
	 * @desc 待回款列表——已回款
	 * @author dangjh
	 * @datetime 2014年12月11日 下午4:47:20
	 */
	@AfterReturning("saveWaitRecon()")
	public void saveWaitRecon(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		MedicalOrderReconClaim order = (MedicalOrderReconClaim) obj[0];
		String[] ids = order.getOrderId().split(",");
		for(String id : ids) {
			// 订单操作日志记录
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("待回款操作   订单回款");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.HAS_SECTIONED, id);
		}
	}
	
	/**
	 * @desc 我的待回款列表-回款切点
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:34:49
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.updateRecon(..))")
	private void updateRecon() {}
	
	/**
	 * @desc 我的待回款列表——已回款
	 * @author dangjh
	 * @datetime 2014年12月11日 下午4:47:20
	 */
	@AfterReturning("updateRecon()")
	public void updateRecon(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		MedicalOrderReconClaim order = (MedicalOrderReconClaim) obj[0];
		String[] ids = order.getOrderId().split(",");
		for(String id : ids) {
			// 订单操作日志记录
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("我的待回款操作   订单回款");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.HAS_SECTIONED, id);
		}
	}
	
	/**---------------------------------------------------------------------------------------------导入对账、回款-----------------------------------------------------------
	 * @desc 货到付款——导入对账(待对账、我的待对账)切点
	 * @author dangjh
	 * 2015年1月5日 上午11:53:23
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.importDelivery(..))")
	private void importDelivery() {}
	
	/**
	 * @desc 货到付款——导入对账(待对账、我的待对账)
	 * @param joinPoint
	 * @author dangjh
	 * 2015年1月7日 下午7:17:15
	 */
	@AfterReturning("importDelivery()")
	public void importDelivery(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[1];
		String type = (String) obj[2];
		Workbook workbook;
		// 快递单号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String ordersExpressNo = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					ordersExpressNo = row.getCell(0).getStringCellValue().trim();
				} else {
					ordersExpressNo = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(ordersExpressNo)) {
					numList.add(ordersExpressNo);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(numList.size() > 0) {
			String expressNos[] = (String[]) numList.toArray();
			this.changeProductStatus(expressNos, SystemConfig.HAS_RECONCILED, type);
		}
	}
	
	/**
	 * @desc 货到付款——导入对账修改产品销售状态
	 * @param expressNos
	 * @param status
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:58:53
	 */
	private void changeProductStatus(String[] expressNos, String status, String type) {
		if(SystemConfig.WAIT_RECONCILED_CASH.equals(type)) {
			for(String expressNo : expressNos) {
				MedicalFinancialOrders claim = (MedicalFinancialOrders) this.iBaseDao.getObjectByHql("from MedicalFinancialOrders m where m.expressNo=? ", expressNo);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("待对账操作   订单对账");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		} else if(SystemConfig.MY_WAIT_RECONCILED_CASH.equals(type)) {
			for(String expressNo : expressNos) {
				MedicalFinancialClaim claim = (MedicalFinancialClaim) this.iBaseDao.getObjectByHql("from MedicalFinancialClaim m where m.expressNo=? ", expressNo);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("我的待对账操作   订单对账");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		}
	}
	
	/**
	 * @desc 线下汇款——导入对账(待对账、我的待对账)切点
	 * @author dangjh
	 * 2015年1月5日 上午11:53:23
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.importLineDelivery(..))")
	private void importLineDelivery() {}
	
	/**
	 * @desc 线下汇款——导入对账(待对账、我的待对账)
	 * @param joinPoint
	 * @author dangjh
	 * 2015年1月7日 下午7:17:15
	 */
	@AfterReturning("importLineDelivery()")
	public void importLineDelivery(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[1];
		String type = (String) obj[2];
		Workbook workbook;
		// 订单号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String ordersSerialNum = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					ordersSerialNum = row.getCell(0).getStringCellValue().trim();
				} else {
					ordersSerialNum = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(ordersSerialNum)) {
					numList.add(ordersSerialNum);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(numList.size() > 0) {
			String expressNos[] = (String[]) numList.toArray();
			this.changeLineProductStatus(expressNos, SystemConfig.HAS_RECONCILED, type);
		}
	}
	
	/**
	 * @desc 线下汇款——导入对账修改产品销售状态
	 * @param serialNums
	 * @param status
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:58:53
	 */
	private void changeLineProductStatus(String[] serialNums, String status, String type) {
		if(SystemConfig.WAIT_RECONCILED_LINE.equals(type)) {
			for(String serialNum : serialNums) {
				MedicalFinancialOrders claim = (MedicalFinancialOrders) this.iBaseDao.getObjectByHql("from MedicalFinancialOrders m where m.serialNum=? ", serialNum);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("待对账操作   订单对账");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		} else if(SystemConfig.MY_WAIT_RECONCILED_LINE.equals(type)) {
			for(String serialNum : serialNums) {
				MedicalFinancialClaim claim = (MedicalFinancialClaim) this.iBaseDao.getObjectByHql("from MedicalFinancialClaim m where m.serialNum=? ", serialNum);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("我的待对账操作   订单对账");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		}
	}
	
	/**
	 * @desc 货到付款——导入回款(待回款、我的待回款)切点
	 * @author dangjh
	 * @datetime 2014年12月17日 下午11:28:57
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.importReconDelivery(..))")
	public void importReconDelivery() {};
	
	/**
	 * @desc 货到付款——导入回款(待回款、我的待回款)
	 * @param joinPoint
	 * @author dangjh
	 * 2015年1月7日 下午7:57:58
	 */
	@AfterReturning("importReconDelivery()")
	public void importReconDelivery(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[1];
		String type = (String) obj[2];
		Workbook workbook;
		// 快递单号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String ordersExpressNo = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					ordersExpressNo = row.getCell(0).getStringCellValue().trim();
				} else {
					ordersExpressNo = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(ordersExpressNo)) {
					numList.add(ordersExpressNo);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(numList.size() > 0) {
			String expressNos[] = (String[]) numList.toArray();
			this.changeReconProductStatus(expressNos, SystemConfig.HAS_SECTIONED, type);
		}
	}
	
	/**
	 * @desc 货到付款——导入回款修改产品销售状态
	 * @param expressNos
	 * @param status
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:58:53
	 */
	private void changeReconProductStatus(String[] expressNos, String status, String type) {
		if(SystemConfig.WAIT_SECTION_CASH.equals(type)) {
			for(String expressNo : expressNos) {
				MedicalOrderReconciliation claim = (MedicalOrderReconciliation) this.iBaseDao.getObjectByHql("from MedicalOrderReconciliation m where m.expressNo=? ", expressNo);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("待回款操作   订单回款");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		} else if(SystemConfig.MY_WAIT_SECTION_CASH.equals(type)) {
			for(String expressNo : expressNos) {
				MedicalOrderReconClaim claim = (MedicalOrderReconClaim) this.iBaseDao.getObjectByHql("from MedicalOrderReconClaim m where m.expressNo=? ", expressNo);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("我的待回款操作   订单回款");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		}
	}
	
	/**
	 * @desc 线下汇款——导入回款(待回款、我的待回款)切点
	 * @author dangjh
	 * @datetime 2014年12月17日 下午11:28:57
	 */
	@Pointcut("execution(* com.fau.fm.service.impl.CheckingManagerService.importLineReconDelivery(..))")
	public void importLineReconDelivery() {};
	
	/**
	 * @desc 线下汇款——导入回款(待回款、我的待回款)
	 * @param joinPoint
	 * @author dangjh
	 * 2015年1月7日 下午7:57:58
	 */
	@AfterReturning("importLineReconDelivery()")
	public void importLineReconDelivery(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[1];
		String type = (String) obj[2];
		Workbook workbook;
		// 快递单号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String ordersSerialNum = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					ordersSerialNum = row.getCell(0).getStringCellValue().trim();
				} else {
					ordersSerialNum = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(ordersSerialNum)) {
					numList.add(ordersSerialNum);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(numList.size() > 0) {
			String serialNums[] = (String[]) numList.toArray();
			this.changeReconLineProductStatus(serialNums, SystemConfig.HAS_SECTIONED, type);
		}
	}
	
	/**
	 * @desc 线下汇款——导入回款修改产品销售状态
	 * @param serialNums
	 * @param status
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:58:53
	 */
	private void changeReconLineProductStatus(String[] serialNums, String status, String type) {
		if(SystemConfig.WAIT_SECTION_LINE.equals(type)) {
			for(String serialNum : serialNums) {
				MedicalOrderReconciliation claim = (MedicalOrderReconciliation) this.iBaseDao.getObjectByHql("from MedicalOrderReconciliation m where m.serialNum=? ", serialNum);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("待回款操作   订单回款");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		} else if(SystemConfig.MY_WAIT_SECTION_LINE.equals(type)) {
			for(String serialNum : serialNums) {
				MedicalOrderReconClaim claim = (MedicalOrderReconClaim) this.iBaseDao.getObjectByHql("from MedicalOrderReconClaim m where m.serialNum=? ", serialNum);
				if(null != claim) {
					// 订单操作日志记录
					MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(claim.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("我的待回款操作   订单回款");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, claim.getId());
				}
			}
		}
	}
	
}
